package com.jinzecloud.reportapproval.utils;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.StrUtil;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.jinzecloud.reportapproval.bean.Admin;
import com.jinzecloud.reportapproval.bean.RoleEntity;
import com.jinzecloud.reportapproval.bean.RoleUserEntity;
import com.jinzecloud.reportapproval.dto.AdminDto;
import com.jinzecloud.reportapproval.enums.StateEnum;
import com.jinzecloud.reportapproval.enums.TableEnums;
import com.jinzecloud.reportapproval.mapper.AdminMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

@Component
public class AuditUtil {


    public static Map<String, List<StateEnum>> AUDIT_INFO_MAP;

    static {
        AUDIT_INFO_MAP = new HashMap<>() {{
            put(TableEnums.REPORT_AND_PRODUCT_INFO.getTableName(), new ArrayList<>() {{
                add(StateEnum.SUBMIT);
                add(StateEnum.APPROVAL);
                add(StateEnum.CHECK);
                add(StateEnum.DEPUTY);
                add(StateEnum.APPROVAL_CHECK);
            }});
            put(TableEnums.SAFETY_ASSESSMENT.getTableName(), new ArrayList<>() {{
                add(StateEnum.CHECK_DETECT);
                add(StateEnum.RECORD);
                add(StateEnum.APPROVAL_CHECK);
            }});
            put(TableEnums.SAMPLE_SHEET.getTableName(), new ArrayList<>(){{
                add(StateEnum.SAMPLE);
                add(StateEnum.DEPARTMENT_HEAD);
            }});
            put(TableEnums.TESTS_SUMMARY_TABLE_SERVICE.getTableName(), new ArrayList<>() {{
                add(StateEnum.PARTICIPANT);
                add(StateEnum.DEPUTY);
                add(StateEnum.TECHNICAL_HEAD);
                add(StateEnum.CHECK_OPINION);
            }});
            put(TableEnums.TESTS_SUMMARY_TABLE.getTableName(), new ArrayList<>() {{
                add(StateEnum.AGGREGATORS);
                add(StateEnum.APPROVAL_CHECK);
            }});
            put(TableEnums.VEGETATION_RECORD_FORM.getTableName(), new ArrayList<>() {{
                add(StateEnum.CHECK_DETECT);
                add(StateEnum.RECORD);
                add(StateEnum.APPROVAL_CHECK);
            }});
            put(TableEnums.SPEED_OPERATION_TABLE.getTableName(), new ArrayList<>() {{
                add(StateEnum.CHECK_DETECT);
                add(StateEnum.RECORD);
                add(StateEnum.APPROVAL_CHECK);
            }});
            put(TableEnums.SOIL_FIRMNESS_MOISTURE.getTableName(), new ArrayList<>() {{
                add(StateEnum.CHECK_DETECT);
                add(StateEnum.RECORD);
                add(StateEnum.APPROVAL_CHECK);
            }});
            put(TableEnums.TEMPERATURE_HUMIDITY.getTableName(), new ArrayList<>() {{
                add(StateEnum.CHECK_DETECT);
                add(StateEnum.RECORD);
                add(StateEnum.APPROVAL_CHECK);
            }});
            put(TableEnums.CONS_CHECK_RECORD.getTableName(), new ArrayList<>() {{
                add(StateEnum.CHECK_DETECT);
                add(StateEnum.RECORD);
                add(StateEnum.APPROVAL_CHECK);
            }});
            put(TableEnums.KEY_INSTRUMENT.getTableName(), new ArrayList<>() {{
                add(StateEnum.CHECK_DETECT);
                add(StateEnum.RECORD);
                add(StateEnum.APPROVAL_CHECK);
            }});
            put(TableEnums.USER_SURVEY_SUMMARY.getTableName(), new ArrayList<>() {{
                add(StateEnum.AGGREGATORS);
                add(StateEnum.APPROVAL_CHECK);
            }});
            put(TableEnums.INSPRESUPRO.getTableName(), new ArrayList<>(){{
                add(StateEnum.DEPARTMENT_HEAD);
                add(StateEnum.CHECK);
                add(StateEnum.DEPARTMENT_HEAD);
                add(StateEnum.DEPARTMENT_HEAD);
                add(StateEnum.DEPARTMENT_HEAD);
                add(StateEnum.DEPARTMENT_HEAD);
            }});
            put(TableEnums.SPECIFICATION.getTableName(),new ArrayList<>(){{
                add(StateEnum.COMPANY_HEAD);
            }});
        }};
    }

    public static List<Integer> getCurrentStateIndex(String tableName, Collection<Integer> stateList) {
        List<Integer> stateIndexList = new ArrayList<>();
        List<StateEnum> enumList = AUDIT_INFO_MAP.get(tableName);
        for (int i = 0; i < enumList.size(); i++) {
            int state = enumList.get(i).getState();
            if (stateList.contains(state)) {
                stateIndexList.add(i);
            }
        }
        return stateIndexList;
    }

    public static StateEnum getStateText(String tableName, int state){
        if (state < 0) return StateEnum.getStateEnum(state);
        List<StateEnum> stateEnums = AUDIT_INFO_MAP.get(tableName);
        return stateEnums.get(state);
    }

    private static Integer getNextState(String tableName, int state, Collection<String> auditRoles){
        StateEnum stateEnum = StateEnum.getStateEnum(state);
        List<StateEnum> auditRoleList = AUDIT_INFO_MAP.get(tableName);
        if (stateEnum.getState() == StateEnum.APPROVAL_NOT_PASS.getState()) return 0;
        int nextIndex = state + 1;
        if (nextIndex >= auditRoleList.size()) return StateEnum.APPROVAL_PASS.getState();
        if (auditRoles.contains(auditRoleList.get(nextIndex).getAuditRole())) return nextIndex;
        return null;
    }

    public static Integer getNextAuditState(String tableName, int state, Collection<String> auditRoles){
        if (state < 0) return 0;
        return getNextState(tableName, state, auditRoles);
    }

    public static AdminMapper adminMapper;

    @Autowired
    public void setAdminMapper(AdminMapper adminMapper) {
        AuditUtil.adminMapper = adminMapper;
    }

    public static List<AdminDto> getAdminDto(String adminUserName) {
        MPJLambdaWrapper<Admin> adminWrapper = new MPJLambdaWrapper<>();
        adminWrapper
                .select(Admin::getAdId, Admin::getAdUserName, Admin::getAdName,Admin::getAdSignature)
                .select(RoleEntity::getRoleName, RoleEntity::getRoleCode)
                .leftJoin(RoleUserEntity.class, RoleUserEntity::getUserId, Admin::getAdId)
                .leftJoin(RoleEntity.class, RoleEntity::getRoleId, RoleUserEntity::getRoleId)
                .eq(Admin::getAdUserName, adminUserName);
        return Optional.ofNullable(adminMapper.selectJoinList(AdminDto.class, adminWrapper))
                .map(list -> list.stream().filter(admin -> StrUtil.isNotBlank(admin.getRoleCode())).toList())
                .orElse(ListUtil.empty());
    }

}
